<template>
	<div>
		<!-- 面包屑导航 -->
		<el-breadcrumb separator-class="el-icon-arrow-right">
			<el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
			<el-breadcrumb-item>权限管理</el-breadcrumb-item>
			<el-breadcrumb-item>角色列表</el-breadcrumb-item>
		</el-breadcrumb>
		<!-- 卡片视图 -->
		<el-card>
			<el-row>
				<el-col>
					<el-button type="primary" @click="addUserButton">添加角色</el-button>
				</el-col>
			</el-row>

			<!-- 角色列表区域 -->
			<el-table :data="rolelist" border stripe>
				<el-table-column label type="expand">
					<template v-slot="scope">
						<el-row :class="['elrow']" v-for="(item1) in scope.row.children" :key="item1.id">
							<!-- 一级权限 -->
							<el-col :span="5">
								<el-tag closable @close="removeRightById(scope.row,item1.id)">{{item1.authName}}</el-tag>
								<i class="el-icon-caret-right"></i>
							</el-col>
							<!-- 二级和三级权限 -->
							<el-col :span="19">
								<!-- 二级权限渲染 -->
								<el-row :class="['elrow2']" v-for="(item2) in item1.children" :key="item2.id">
									<el-col :span="6">
										<el-tag
											type="success"
											closable
											@close="removeRightById(scope.row,item2.id)"
										>{{item2.authName}}</el-tag>
										<i class="el-icon-caret-right"></i>
									</el-col>
									<el-col :span="18">
										<!-- 三级权限渲染 -->
										<el-tag
											type="warning"
											closable
											v-for="item3 in item2.children"
											:key="item3.id"
											@close="removeRightById(scope.row,item3.id)"
										>{{item3.authName}}</el-tag>
									</el-col>
								</el-row>
							</el-col>
						</el-row>
					</template>
				</el-table-column>
				<el-table-column label="#" type="index"></el-table-column>
				<el-table-column label="角色名称" prop="roleName"></el-table-column>
				<el-table-column label="角色描述" prop="roleDesc"></el-table-column>
				<el-table-column label="操作" prop="level" width="300px">
					<template v-slot="scope">
						<!-- 修改按钮 -->
						<el-button
							type="primary"
							icon="el-icon-edit"
							size="mini"
							@click="showEditDialog(scope.row)"
						>编辑</el-button>
						<!-- 删除按钮 -->
						<el-button
							type="danger"
							icon="el-icon-delete"
							size="mini"
							slot="reference"
							@click="removeRoleById(scope.row.id)"
						>删除</el-button>
						<!-- 分配角色按钮 -->
						<el-tooltip effect="dark" content="分配角色" placement="top" :enterable="false">
							<el-button
								type="warning"
								icon="el-icon-setting"
								size="mini"
								@click="showSetRightDialog(scope.row)"
							>分配权限</el-button>
						</el-tooltip>
					</template>
				</el-table-column>
			</el-table>

			<!-- dialog对话框区域 -->
			<!-- 分配权限对话框 -->
			<el-dialog title="分配权限" :visible.sync="setRightDialogVisible" width="50%">
				<el-tree
					:data="rightslist"
					:props="treeProps"
					show-checkbox
					node-key="id"
					default-expand-all
					:default-checked-keys="defKeys"
					ref="treeRef"
				></el-tree>
				<span slot="footer" class="dialog-footer">
					<el-button @click="setRightDialogVisible = false">取 消</el-button>
					<el-button type="primary" @click="allotRights">确 定</el-button>
				</span>
			</el-dialog>

			<!-- 添加角色对话框 -->
			<el-dialog title="添加角色" :visible.sync="addDialogVisible" width="50%" @closed="dialogClosed">
				<el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="80px">
					<el-form-item label="角色名称" prop="roleName">
						<el-input v-model="addForm.roleName"></el-input>
					</el-form-item>
					<el-form-item label="角色描述" prop="roleDesc">
						<el-input v-model="addForm.roleDesc"></el-input>
					</el-form-item>
				</el-form>

				<span slot="footer" class="dialog-footer">
					<el-button @click="addDialogVisible = false">取 消</el-button>
					<el-button type="primary" @click="addUser">确 定</el-button>
				</span>
			</el-dialog>

			<!-- 编辑角色对话框 -->
			<el-dialog title="编辑角色" :visible.sync="editDialogVisible" width="50%" @closed="editdialogClosed">
				<el-form :model="editForm" :rules="editFormRules" ref="editFormRef" label-width="80px">
					<el-form-item label="角色名称" prop="roleName">
						<el-input v-model="editForm.roleName"></el-input>
					</el-form-item>
					<el-form-item label="角色描述" prop="roleDesc">
						<el-input v-model="editForm.roleDesc"></el-input>
					</el-form-item>
				</el-form>

				<span slot="footer" class="dialog-footer">
					<el-button @click="editDialogVisible = false">取 消</el-button>
					<el-button type="primary" @click="editUser">确 定</el-button>
				</span>
			</el-dialog>
		</el-card>
	</div>
</template>

<script>
export default {
	data() {
		return {
			//所有角色列表
			rolelist: [],
			setRightDialogVisible: false,
			rightslist: [],
			treeProps: {
				children: 'children',
				label: 'authName'
			},
			roleId: '',
			defKeys: [],
			addDialogVisible: false,
			addForm: {
				roleName: '',
				roleDesc: ''
			},
			addFormRules: {
				roleName: [
					{
						required: true,
						message: '请输入角色名称',
						trigger: 'blur'
					},
					{
						min: 2,
						max: 10,
						message: '长度在 2 到 10 个字符',
						trigger: 'blur'
					}
				],
				roleDesc: [
					{
						required: true,
						message: '请输入角色描述',
						trigger: 'blur'
					},
					{
						min: 2,
						max: 15,
						message: '长度在 2 到 15 个字符',
						trigger: 'blur'
					}
				]
			},
			editDialogVisible: false,
			editForm: {
				roleName: '',
				roleDesc: ''
			},
			editFormRules: {
				roleName: [
					{
						required: true,
						message: '请输入角色名称',
						trigger: 'blur'
					},
					{
						min: 2,
						max: 10,
						message: '长度在 2 到 10 个字符',
						trigger: 'blur'
					}
				],
				roleDesc: [
					{
						required: true,
						message: '请输入角色描述',
						trigger: 'blur'
					},
					{
						min: 2,
						max: 15,
						message: '长度在 2 到 15 个字符',
						trigger: 'blur'
					}
				]
			}
		}
	},
	created() {
		this.getRolesList()
	},
	methods: {
		async getRolesList() {
			//获取角色列表
			const { data: res } = await this.$http.get('roles')
			if (res.meta.status !== 200) {
				return this.$message.error({
					message: res.meta.msg,
					offset: 100
				})
			}
			this.rolelist = res.data
		},
		async removeRightById(role, rightId) {
			//根据id删除权限
			const confirmResult = await this.$confirm(
				'此操作将永久删除该文件, 是否继续?',
				'提示',
				{
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				}
			).catch(err => err)

			if (confirmResult != 'confirm') {
				return this.$message.info({
					message: '已取消删除',
					offset: 100
				})
			}
			const { data: res } = await this.$http.delete(
				`roles/${role.id}/rights/${rightId}`
			)
			if (res.meta.status !== 200) {
				return this.$message.error({
					message: res.meta.msg,
					offset: 100
				})
			}
			this.$message.success({
				message: res.meta.msg,
				offset: 100
			})
			// this.getRolesList()
			role.children = res.data
		},
		async showSetRightDialog(role) {
			//分配权限的事件
			this.roleId = role.id
			const { data: res } = await this.$http.get('rights/tree')
			if (res.meta.status !== 200) {
				return this.$message.error({
					message: res.meta.msg,
					offset: 100
				})
			}

			this.rightslist = res.data
			this.defKeys = []
			this.getLeafKeys(role, this.defKeys)

			this.setRightDialogVisible = true
		},
		getLeafKeys(node, arr) {
			//递归形式获取三级权限ID
			if (!node.children) {
				return arr.push(node.id)
			}
			node.children.forEach(item => this.getLeafKeys(item, arr))
		},
		async allotRights() {
			//分配权限对话框的确定按钮
			const keys = [
				...this.$refs.treeRef.getCheckedKeys(),
				...this.$refs.treeRef.getHalfCheckedKeys()
			]
			const keysStr = keys.join(',')
			const { data: res } = await this.$http.post(
				`roles/${this.roleId}/rights`,
				{
					rids: keysStr
				}
			)
			if (res.meta.status !== 200) {
				return this.$message.error({
					message: res.meta.msg,
					offset: 100
				})
			}
			this.$message.success({
				message: res.meta.msg,
				offset: 100
			})
			this.getRolesList()
			this.setRightDialogVisible = false
		},
		addUserButton() {
			this.addDialogVisible = true
		},
		dialogClosed() {
			this.$refs.addFormRef.resetFields()
		},
		addUser() {
			//添加角色对话框
			this.$refs.addFormRef.validate(async valid => {
				if (valid) {
					const { data: res } = await this.$http.post(
						'roles',
						this.addForm
					)
					if (res.meta.status !== 201) {
						return this.$message.error({
							message: res.meta.msg,
							offset: 100
						})
					}
					this.$message.success({
						message: res.meta.msg,
						offset: 100
					})
					this.addDialogVisible = false
					this.getRolesList()
				} else {
					alert('请输入完整的信息')
					return false
				}
			})
		},
		showEditDialog(role) {
			this.editDialogVisible = true
			this.editForm = role
		},
		editdialogClosed() {
			this.$refs.editFormRef.resetFields()
		},
		editUser() {
			this.$refs.editFormRef.validate(async valid => {
				if (valid) {
					const { data: res } = await this.$http.put(
						'roles/' + this.editForm.id,
						{
							roleName: this.editForm.roleName,
							roleDesc: this.editForm.roleDesc
						}
					)
					if (res.meta.status !== 200) {
						return this.$message.error({
							message: res.meta.msg,
							offset: 100
						})
					}
					this.$message.success({
						message: res.meta.msg,
						offset: 100
					})
					this.editDialogVisible = false
					this.getRolesList()
				} else {
					alert('请输入完整的信息')
					return false
				}
			})
		},
		async removeRoleById(id) {
			const confirmResult = await this.$confirm(
				'此操作将永久删除该角色, 是否继续?',
				'提示',
				{
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				}
			).catch(() => {
				this.$message({
					type: 'info',
					message: '已取消删除',
					offset: 100
				})
			}) //点击确定返回字符串confirm，点击返回返回字符串cancel
			if (confirmResult !== 'confirm') {
				return
			}
			const { data: res } = await this.$http.delete('roles/' + id)
			if (res.meta.status !== 200) {
				return this.$message.error({
					message: res.meta.msg,
					offset: 100
				})
			}
			this.$message({
				type: 'success',
				message: '删除成功!',
				offset: 100
			})
			this.getRolesList()
		}
	}
}
</script>
<style lang="less" scoped>
.elrow:nth-of-type(1) {
	border-top: 1px solid #eee;
}
.elrow {
	border-bottom: 1px solid #eee;
	display: flex;
	align-items: center;
	.el-tag {
		margin: 7px;
	}
	.elrow2:nth-of-type(1) {
		border: none;
	}
	.elrow2 {
		border-top: 1px solid #eee;
		display: flex;
		align-items: center;
	}
}
</style>